﻿// 

namespace CSharpNewFeatures;

/// <summary>
/// 可异步的多线程测试的完整示例。
/// 1. 一个主要线程 Run()
/// 2. 一个任务线程 StartTask()
/// 3. 一个监视线程 StartMonitor()
/// 当任务线程结束后，通过 CancellationTokenSource 取消监控线程。
/// </summary>
public class Demo_PeriodicTimerExample01 : CsharpDemoBase
{
    public bool testMode = true;
    public int value = 0;


    CancellationTokenSource cts = new CancellationTokenSource();

    public override void Run()
    {
        StartTask();
        StartMonitor();

        print("Processing other tasks...");
        for (int i = 0; i < 6; i++)
        {
            print($"Main: value = {value}");
            Thread.Sleep(1200);
        }

        for (int i = 0; i < 3; i++)
        {
            print($"Main: processing other task {i}...");
            Thread.Sleep(TimeSpan.FromSeconds(0.5));

        }

    }

    public void StartTask()
    {
        print("Task: Start.");
        cts.Token.Register(() =>
        {
            print($"Task: cts.processing value = {value}...");
            Thread.Sleep(500);
        });

        try
        {
            Task.Run(() =>
            {
                print("Task: Start looping.");
                while (value < 5) 
                {
                    print($"Task: value = {value}");
                    Thread.Sleep(500);
                }
                print("Task: End looping.");
                Thread.Sleep(500);

                // 任务结束，同时也取消 cts相关任务
                print("Task: cts.Cancel()");
                cts.Cancel();
            });
        }
        catch (Exception ex)
        {
            print("Task: terminated because " + ex.Message);
        }
    }

    public async void StartMonitor()
    {
        print("Monitor: Start.");
        var timer = new PeriodicTimer(TimeSpan.FromMilliseconds(1000));
        try
        {
            while (await timer.WaitForNextTickAsync(cts.Token))
            {
                print($"Monitor: check value = {value}");
                value++;
            }
        }
        catch
        {
            print("Monitor: terminated.");
        }
        print("Monitor: Done.");
    }

}

